import logging
import time
from dataclasses import dataclass, field
from datetime import datetime
from typing import Dict, List, Optional


@dataclass
class 性能数据:
    """单个监控点的性能数据"""
    名称: str
    调用次数: int = 0
    总耗时: float = 0.0
    最大耗时: float = 0.0
    最小耗时: float = float('inf')
    最后调用时间: Optional[datetime] = None
    样本数据: List[float] = field(default_factory=list)
    
    def 添加样本(self, 耗时: float):
        """添加一个新的性能样本"""
        self.调用次数 += 1
        self.总耗时 += 耗时
        self.最大耗时 = max(self.最大耗时, 耗时)
        self.最小耗时 = min(self.最小耗时, 耗时)
        self.最后调用时间 = datetime.now()
        self.样本数据.append(耗时)
        if len(self.样本数据) > 100:  # 只保留最近100个样本
            self.样本数据.pop(0)
            
    @property
    def 平均耗时(self) -> float:
        """计算平均耗时"""
        return self.总耗时 / self.调用次数 if self.调用次数 > 0 else 0.0

class 性能监控器:
    """性能监控器类，用于跟踪和分析程序性能"""
    
    def __init__(self):
        self.logger = logging.getLogger("性能监控器")
        self.性能数据: Dict[str, 性能数据] = {}
        self._当前监控: Dict[str, float] = {}
        self.是否启用 = True
        
    def 开始监控(self, 名称: str):
        """开始监控某个操作"""
        if not self.是否启用:
            return
            
        if 名称 not in self.性能数据:
            self.性能数据[名称] = 性能数据(名称=名称)
            
        self._当前监控[名称] = time.time()
        
    def 结束监控(self, 名称: str):
        """结束监控某个操作"""
        if not self.是否启用 or 名称 not in self._当前监控:
            return
            
        耗时 = time.time() - self._当前监控.pop(名称)
        self.性能数据[名称].添加样本(耗时)
        
        # 记录较慢的操作
        if 耗时 > 0.1:  # 超过100ms的操作
            self.logger.warning(f"性能警告: {名称} 耗时 {耗时:.3f}秒")
            
    def 获取性能报告(self) -> Dict[str, Dict]:
        """获取所有监控点的性能报告"""
        return {
            名称: {
                "调用次数": 数据.调用次数,
                "平均耗时": 数据.平均耗时,
                "最大耗时": 数据.最大耗时,
                "最小耗时": 数据.最小耗时,
                "最后调用": 数据.最后调用时间.strftime("%Y-%m-%d %H:%M:%S") if 数据.最后调用时间 else None
            }
            for 名称, 数据 in self.性能数据.items()
        }
        
    def 获取详细报告(self, 名称: str) -> Optional[Dict]:
        """获取指定监控点的详细性能报告"""
        if 名称 not in self.性能数据:
            return None
            
        数据 = self.性能数据[名称]
        return {
            "名称": 数据.名称,
            "调用次数": 数据.调用次数,
            "平均耗时": 数据.平均耗时,
            "最大耗时": 数据.最大耗时,
            "最小耗时": 数据.最小耗时,
            "总耗时": 数据.总耗时,
            "最后调用": 数据.最后调用时间.strftime("%Y-%m-%d %H:%M:%S") if 数据.最后调用时间 else None,
            "最近样本": 数据.样本数据[-10:]  # 最近10个样本
        }
        
    def 清除性能数据(self, 名称: Optional[str] = None):
        """清除性能数据
        
        Args:
            名称: 要清除的监控点名称，如果为None则清除所有数据
        """
        if 名称:
            self.性能数据.pop(名称, None)
            self._当前监控.pop(名称, None)
        else:
            self.性能数据.clear()
            self._当前监控.clear()
            
    def 导出性能报告(self, 文件路径: str):
        """将性能报告导出到文件"""
        try:
            import json
            with open(文件路径, 'w', encoding='utf-8') as f:
                json.dump(self.获取性能报告(), f, ensure_ascii=False, indent=2)
            self.logger.info(f"性能报告已导出到: {文件路径}")
        except Exception as e:
            self.logger.error(f"导出性能报告失败: {str(e)}")
            
# 创建全局性能监控器实例
性能监控器实例 = 性能监控器() 